import axios, { AxiosRequestHeaders, AxiosResponse, InternalAxiosRequestConfig } from 'axios'
import router from '../router'
import { useUserStore } from '@/stores/user'
import { message } from 'ant-design-vue'

type TAxiosOption = {
  timeout: number
  baseURL: string
}

const baseUrl = 'http://localhost:8888'

const config: TAxiosOption = {
  timeout: 1000 * 60 * 10,
  baseURL: baseUrl
}

class Http {
  service

  baseUrl = baseUrl

  constructor(config: TAxiosOption) {
    this.service = axios.create(config)

    /* 请求拦截 */
    this.service.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        const userInfoStore = useUserStore()
        if (userInfoStore.token) {
          ;(config.headers as AxiosRequestHeaders).Authorization = userInfoStore.token as string
        } else {
          if (router.currentRoute.value.path !== '/login') {
            router.push('/login')
          }
        }
        return config
      },
      (error) => {
        return Promise.reject(error)
      }
    )

    /* 响应拦截 */
    this.service.interceptors.response.use(
      (response: AxiosResponse<any>) => {
        switch (response.data.code) {
          case 200:
            return response.data
          case 401:
            message.error('未获得访问权限！')
            return router.push('/login')
          case 403:
            message.error('您还未登陆，请先登录！')
            return router.push('/login')
          case 500:
            message.error((response.data && response.data.message) || '服务器错误')
            return (response && response.data) || {}
          default:
            return response.data
        }
      },
      (error) => {
        return Promise.reject(error)
      }
    )
  }

  /* GET 方法 */
  get<T>(url: string, params?: object, _object = {}): Promise<any> {
    return this.service.get(url, { params, ..._object })
  }

  /* POST 方法 */
  post<T>(url: string, params?: object, _object = {}): Promise<any> {
    return this.service.post(url, params, _object)
  }

  /* PUT 方法 */
  put<T>(url: string, params?: object, _object = {}): Promise<any> {
    return this.service.put(url, params, _object)
  }

  /* DELETE 方法 */
  delete<T>(url: string, params?: any, _object = {}): Promise<any> {
    return this.service.delete(url, { params, ..._object })
  }
}

export default new Http(config)
